﻿using DevelopTool.Common;
using DevelopTool.Forms.BaseForms;
using Sunny.UI;
using System;
using System.Drawing;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DevelopTool.Forms.LodingForm
{
    public partial class LodingForm : BaseUIForm
    {
        /// <summary>
        /// 提示消息文本
        /// </summary>
        public string Message { get; set; }


        /// <summary>
        /// 工作异常
        /// </summary>
        public Exception WorkException { get; private set; }

        /// <summary>
        /// 工作动作
        /// </summary>
        private Action _workAction;

        /// <summary>
        /// 工作是否完成
        /// </summary>
        private bool _isWorkCompleted;

        /// <summary>
        /// 任务开始时间
        /// </summary>
        private TimeSpan _startTime;

        private CancellationTokenSource cancellationToken = new CancellationTokenSource();



        //设置此窗体为活动窗体：
        //将创建指定窗口的线程带到前台并激活该窗口。键盘输入直接指向窗口，并为用户更改各种视觉提示。
        //系统为创建前台窗口的线程分配的优先级略高于其他线程。
        [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        //设置此窗体为活动窗体：
        //激活窗口。窗口必须附加到调用线程的消息队列。
        [DllImport("user32.dll", EntryPoint = "SetActiveWindow")]
        public static extern IntPtr SetActiveWindow(IntPtr hWnd);

        //设置窗体位置
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);


        /// <summary>
        /// 初始化加载窗口
        /// </summary>
        /// <param name="message">显示文本</param>
        /// <param name="work">执行的方法</param>
        /// <param name="topMost">是否显示在顶层</param>
        public LodingForm(string message, Action work, bool topMost = false)
        {
            InitializeComponent();

            if (topMost)
            {
                // 设置窗体显示在最上层
                SetWindowPos(this.Handle, -1, 0, 0, 0, 0, 0x0001 | 0x0002 | 0x0010 | 0x0080);

                // 设置本窗体为活动窗体
                SetActiveWindow(this.Handle);
                SetForegroundWindow(this.Handle);

                // 设置窗体置顶
                this.TopMost = true;
            }

            Message = message;
            LblMessage.Text = message;
            _workAction = work;
            _startTime = new TimeSpan(DateTime.Now.Ticks);//设置工作开始时间

        }


        private void LodingForm_Load(object sender, EventArgs e)
        {
            ThemHelper.SetSystemThem(this);

            switch (Setting.Theme.ControlThemColor)
            {
                case UIMenuStyle.Black:
                    LblMessage.BackColor = ThemHelper.CustomBackColor_Black;
                    LblMessage.ForeColor = Setting.Theme.BackColor;
                    break;
                case UIMenuStyle.White:
                    LblMessage.BackColor = ThemHelper.CustomBackColor_White;
                    LblMessage.ForeColor = Setting.Theme.BackColor;
                    break;
            }

            if (_workAction == null)
            {
                _isWorkCompleted = true;
                return;
            }

            Task.Factory.StartNew(() => ExecWorkAction(), TaskCreationOptions.LongRunning);            
        }

        /// <summary>
        /// 执行工作动作
        /// </summary>
        private void ExecWorkAction()
        {
            try
            {
                Task.Factory.StartNew(() => _workAction(), cancellationToken.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default).Wait();//异步执行方法
            }
            catch (Exception exception)
            {
                this.WorkException = exception.InnerException ?? exception;
            }
            finally
            {
                _isWorkCompleted = true;
            }
        }

        private void uiWaitingBar_Tick(object sender, EventArgs e)
        {
            if (_isWorkCompleted)
            {
                // Close();
                // Dispose();
                this.DialogResult = DialogResult.OK;
            }
            else
            {
                //设置耗时文本
                TimeSpan ts = _startTime.Subtract(new TimeSpan(DateTime.Now.Ticks)).Duration();
                LblMessage.Text = $"{Message}，耗时：{ts.TotalSeconds.ToDouble(1)}秒";
            }
        }

        private void LodingForm_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            cancellationToken.Cancel();
            _isWorkCompleted = true;
        }
    }
}
